#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define DEBUG(fmt,...) printf("[file:%s,line:%d,func:%s]"fmt,__FILE__,__LINE__,__func__,##__VA_ARGS__)
#define ERROR(msg) do{\
                    printf("file:%s,line:%d,func:%s\n",__FILE__,__LINE__,__func__);\
                    perror(msg);\
                    exit(-1);\
                    }while(0);

int main(int argc,const char* argv[])
{
    if(argc != 3){
        DEBUG("argc is invalid , argc must be 3,argc = %d\n",argc);
        exit(-1);
    }

    int sockfd = -1;
    int acceptfd = -1;
    struct sockaddr_in serveraddr,clientaddr;
    socklen_t len = sizeof(serveraddr);

    memset(&serveraddr,0,sizeof(serveraddr));
    memset(&clientaddr,0,sizeof(clientaddr));

    //创建网络套接字
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1){
        ERROR("socket create is failed!");
    }
    
    //填充网络信息结构体
    serveraddr.sin_family =  AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    //绑定网络信息结构体
    if(bind(sockfd,(struct sockaddr*)&serveraddr,len)==-1){
        ERROR("bind is failed!");
    }

    //设置被动监听状态
    if(listen(sockfd,5)==-1){
        ERROR("listen is failed!");
    }

    fd_set readfds;
    FD_ZERO(&readfds);

    int maxfd=sockfd+1;
    char buf[128]={0};
    while(1){
        FD_SET(0,&readfds);
        FD_SET(sockfd,&readfds);
        if(select(maxfd,&readfds,NULL,NULL,NULL)==-1){
            ERROR("select is failed!");
        }

        if(FD_ISSET(0,&readfds)){
            fgets(buf,sizeof(buf),stdin);
            buf[strlen(buf)-1]='\0';
            // if(send(sockfd,buf,sizeof(buf),0)==-1){
            //     ERROR("send is failed!");
            // }
            printf("buf=%s\n",buf);
            FD_CLR(0,&readfds);
        }
        
        if(FD_ISSET(sockfd,&readfds)){
            if((acceptfd=accept(sockfd,(struct sockaddr*)&clientaddr,&len))==-1){
                ERROR("accept is failed!");
            }
            printf("Client:[%s,%d]Linked\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
            FD_CLR(sockfd,&readfds);
        }

    }
    return 0;
}